home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Science / RLaB / misc / gnu_plot.r < prev    next >
Text File  |  1994-04-25  |  8KB  |  417 lines

  1. //-------------------------------------------------------------------//
  2.  
  3. //  Syntax:    plot ( A , I )
  4. //        pclose ( I )
  5. //        phrd ( I )
  6. //        setterm ( TERM , I )
  7. //        showplot ( I )
  8.  
  9. //  Description:
  10.  
  11. //  The plot function plots numeric data via the GNUPLOT program. The
  12. //  argument A can be a matrix, or a list of matrices, or a string.
  13. //  When A is a matrix, columns 2 through N are plotted versus the 1st
  14. //  column. When A is a list of matrices, each matrix is plotted
  15. //  versus it's own 1st column. When A is a string, the string is sent
  16. //  to GNUPLOT as a command.
  17.  
  18. //    plot ( M )        // plots the contents of matrix M
  19. //    plot ( << M1; M2>> )    // plots M1, and M2 on the same graph
  20. //    plot ("replot")        // sends the string directly to
  21. //                // GNUPLOT as a command
  22.  
  23. //  Using a list of matrices as an argument to plot is useful when the
  24. //  the independent variable (1st column) of each matrix is different.
  25.  
  26. //  The second, and optional argument to plot denotes the plot process
  27. //  number. The plot function will open distinct plot processes when
  28. //  given distinct values of N. When this feature is used in a
  29. //  X-windows environment, the effect is to create separate plot
  30. //  windows. For example:
  31.  
  32. //      plot (M);        // plot the contents if matrix M
  33. //      plot (2.*M, 1);        // plot 2 times M, to another window
  34.  
  35. //  The pclose function closes (destroys)  the I-th GNUPLOT
  36. //  subprocess. 
  37.  
  38. //  The phrd function generates a PostScript file of the current I-th
  39. //  plot. The PostScript plot is save in a file for printing, or
  40. //  whatever. Immediately after calling phrd(), the GNUPLOT variables
  41. //  term, and output are reset to there former values.
  42.  
  43. //  The setterm function allows the user to set/reset the I-th plot's
  44. //  term type. The argument TERM is a string that corresponds to one
  45. //  of GNUPLOT's available term types, for example "vttek".
  46.  
  47. //  The showplot function prints the contents of the I-th plot list to
  48. //  stdout. 
  49.  
  50. //  The plot function is an interface to the GNUPLOT program. The plot
  51. //  function uses temporary files and Rlab's piping capability to
  52. //  transparently plot numerical data via GNUPLOT. Since the plot
  53. //  function is an rfile, it could easily be modified to to use
  54. //  another plotting program.
  55.  
  56. //-------------------------------------------------------------------//
  57.  
  58.  
  59. //
  60. // List to contain plot-object lists.
  61. //
  62.  
  63. static (p);
  64. p = <<>>;
  65.  
  66. //
  67. // Internal plot-related functions
  68. //
  69.  
  70. static (plotl, plotm, plots);
  71. static (pobj_Create, pobj_Reset, pobj_Destroy);
  72. static (pobj_TmpFileName, pobj_WriteData, pobj_PlotCmd);
  73. static (pobj_Plot, pobj_SetRm, pobj_Rm);
  74.  
  75. //
  76. // User interface to plot functionality
  77. //
  78.  
  79. plot = function ( data , N )
  80. {
  81.   if (!exist (N)) { N = 0; }    // Always the default plot-object
  82.  
  83.   // Check the existence of p.[N]
  84.   if (max (size (N)) != 1) { error ("plot(): N must be a 1-by-1"); }
  85.   if (exist (p.[N])) 
  86.   {
  87.     pobj_Reset (N);
  88.   else
  89.     pobj_Create (N);
  90.   }
  91.  
  92.   if (class (data) == "num") 
  93.   {
  94.     pobj_Rm (N);
  95.     plotm (data, N, 1);
  96.     pobj_Plot (N);
  97.     pobj_SetRm (N);
  98.   else if (class (data) == "string") {
  99.     plots (data, N);
  100.     pobj_Plot (N);
  101.   else if (class (data) == "list") {
  102.     pobj_Rm (N);
  103.     plotl (data, N);
  104.     pobj_Plot (N);
  105.     pobj_SetRm (N);   
  106.   else
  107.     error ("Invalid data for plot()");
  108.   }}}
  109.  
  110. };
  111.  
  112. pclose = function ( N )
  113. {
  114.   if (!exist (N)) { N = 0; }
  115.   if (!exist (p.[N])) { return -1; }
  116.   close (p.[N].rmf);
  117.   close (p.[N].prog);
  118.   pobj_Destroy (N);
  119.   return N;
  120. };
  121.  
  122. phrd = function ( N )
  123. {
  124.   if (!exist (N)) { N = 0; }
  125.   if (!exist (p.[N])) 
  126.   {
  127.     error ("No existing plot to make hardcopy from");
  128.   }
  129.  
  130.   //
  131.   // Make hardcopy file
  132.   //
  133.  
  134.   fprintf (p.[N].prog, "set term %s\n", p.[N].hrd);
  135.   fprintf (p.[N].prog, "set output \"%s\"\n", p.[N].hrdf);
  136.   fprintf (p.[N].prog, "replot\n");
  137.  
  138.   //
  139.   // Reset to original term type, and replot
  140.   //
  141.  
  142.   fprintf (p.[N].prog, "set term %s\n", p.[N].term);
  143.   fprintf (p.[N].prog, "set output \"%s\"\n", p.[N].output);
  144.   fprintf (p.[N].prog, "replot\n");
  145. };
  146.  
  147. //
  148. // Set the terminal type for the I-th GNUPLOT process
  149. //
  150.  
  151. setterm = function ( TERM, N )
  152. {
  153.   if (!exist (N)) { N = 0; }
  154.   if (!exist (p.[N]))
  155.   {
  156.     pobj_Create (N);
  157.   }
  158.   p.[N].term = TERM;
  159.  
  160.   //
  161.   // Now send the "set term" command to GNUPLOT
  162.   //
  163.  
  164.   fprintf (p.[N].prog, "set term %s\n", TERM);
  165. };
  166.  
  167. //
  168. // Print out the plot list
  169. //
  170.  
  171. showplot = function ( N )
  172. {
  173.   if (!exist (N)) { N = 0; }
  174.   if (!exist (p.[N]))
  175.   {
  176.     pobj_Create (N);
  177.   }
  178.  
  179.   printf ("\tPlot List %i\n", N);
  180.   printf ("\t\tTerm:\t\t\t%s\n", p.[N].term);
  181.   printf ("\t\tOutput:\t\t\t%s\n", p.[N].output);
  182.   printf ("\t\tTmp Files:\t\t%s\n", p.[N].files);
  183.   printf ("\t\tHardCopy:\t\t%s\n", p.[N].hrd);
  184.   printf ("\t\tHardCopy Files:\t\t%s\n", p.[N].hrdf);
  185. };
  186.   
  187. //====================
  188. // Static Functions  =
  189. //====================
  190.  
  191. plotl = function ( data, N )
  192. {
  193.   local (I, i);
  194.   I = 1;
  195.   for (i in members (data))
  196.   {
  197.     if (class (data.[i]) == "num")
  198.     {
  199.       plotm (data.[i], N, I);
  200.       I++;
  201.     }
  202.   }
  203. };
  204.  
  205. //
  206. // Set-Up to plot a matrix. Columns 2...N against 1st column.
  207. //
  208.  
  209. plotm = function ( data , N, I )
  210. {
  211.   local (ans, fn, i, nplot);
  212.   
  213.   // Determine how many lines to draw
  214.   nplot = max ([1, data.nc - 1]);
  215.  
  216.   if (nplot > data.nr)
  217.   {
  218.     printf (" Plot %i columns, are you sure (y/n) ? ", data.nc);
  219.     ans = getline ("stdin");
  220.     if (ans.[1] != "y")
  221.     {
  222.       return 0;
  223.     }
  224.   }
  225.  
  226.   // Generate two column matrices for plot program
  227.   for (i in 1:nplot)
  228.   {
  229.     // Create tmp-file-name
  230.     fn = pobj_TmpFileName (N, i, I);
  231.  
  232.     // Write data to tmp-file
  233.     // Add to plot command
  234.     if (nplot == 1)
  235.     {
  236.       pobj_WriteData (real (data), fn);
  237.       pobj_PlotCmd (N, i, "C", fn);
  238.     else
  239.       pobj_WriteData (real (data[;1,i+1]), fn);
  240.       pobj_PlotCmd (N, i, "C", fn);
  241.     }
  242.   }
  243. };
  244.  
  245. //
  246. // Form a plain string to send to GNUPLOT as 
  247. // command
  248. //
  249.  
  250. plots = function ( data , N )
  251. {
  252.   // Send the string to GNUPLOT
  253.  
  254.   p.[N].pcmd = data + "\n";
  255. };
  256.  
  257. //
  258. // Create a plot-object.
  259. //
  260.  
  261. pobj_Create = function ( N )
  262. {
  263.   local (plist);
  264.  
  265.   plist.files = "";        // The tmp files to plot
  266.   plist.pcmd = "";        // Where the plot command will go
  267.  
  268.   //
  269.   // Init string for plotting program
  270.   //
  271.  
  272.   plist.init = "set grid\nset data style lines\n";
  273.  
  274.   //
  275.   // The program that draws the plot(s)
  276.   //
  277.  
  278.   sprintf (plist.prog, "|gnuplot #%i", N);
  279.  
  280.   //
  281.   // To remove tmp-files
  282.   //
  283.  
  284.   sprintf (plist.rmf, "|rm -f `cat` #%i", N);
  285.  
  286.   //
  287.   // Keep track of terminal type, and output
  288.   //
  289.  
  290.   plist.term = "X11";
  291.   plist.output = "stdout";
  292.  
  293.   //
  294.   // To generate hardcopy
  295.   //
  296.  
  297.   plist.hrd = "postscript";
  298.   sprintf (plist.hrdf, "rlab-tmp-hrdf.%i", N);
  299.  
  300.   //
  301.   // Copy the local list into the static plot-object collection
  302.   //
  303.  
  304.   p.[N] = plist;
  305.   fprintf (p.[N].prog, "%s", p.[N].init);
  306.   fprintf (p.[N].prog, "set term %s\n", p.[N].term);
  307. };
  308.  
  309. //
  310. // Reset a plot object to plot new data
  311. //
  312.  
  313. pobj_Reset = function ( N )
  314. {
  315.   //
  316.   // Close any existing tmp-files that belong
  317.   // to plot-object N. Reset the file-name list.
  318.   //
  319.  
  320.   p.[N].files = "";
  321.   p.[N].pcmd = "";
  322. };
  323.  
  324. //
  325. // Destroy a plot-object
  326. //
  327.  
  328. pobj_Destroy = function ( N )
  329. {
  330.   if (exist (p.[N]))
  331.   {
  332.     clear (p.[N]);  
  333.   }
  334. };
  335.  
  336. //
  337. // Create a tmp-file name
  338. //
  339.  
  340. pobj_TmpFileName = function ( N, i, j )
  341. {
  342.   local (tmp);
  343.   sprintf (tmp, "rlab-tmpf-%i-%i-%i", N, i, j);
  344.   p.[N].files = p.[N].files + " " + tmp;
  345.   return tmp;
  346. };
  347.  
  348. //
  349. // Add data-file (tmp-file) to plot object list of stuff
  350. // to be plotted.
  351. //
  352.  
  353. pobj_WriteData = function ( m, file )
  354. {
  355.   write (file, m);
  356.   close (file);
  357. };
  358.  
  359. //
  360. // Create the command(s) to plot all the data in the plot object.
  361. //
  362.  
  363. pobj_PlotCmd = function ( N, i, nm, fn )
  364. {
  365.   local (tmp);
  366.  
  367.   if(p.[N].pcmd == "") 
  368.   {
  369.     sprintf(tmp, "plot '%s' title '%s-%i'", fn, nm, i+1);
  370.   else
  371.     sprintf(tmp,    ", '%s' title '%s-%i'", fn, nm, i+1);
  372.   }
  373.  
  374.   p.[N].pcmd = p.[N].pcmd + tmp;
  375. };
  376.  
  377. //
  378. // Force the plot program to create the plot
  379. //
  380.  
  381. pobj_Plot = function ( N )
  382. {
  383.   //  fprintf ("stdout", "%s\n", p.[N].pcmd);
  384.   fprintf (p.[N].prog, "%s\n", p.[N].pcmd);
  385. };
  386.  
  387. //
  388. // Setup so the tmp-files can be removed
  389. //
  390.  
  391. pobj_SetRm = function ( N )
  392. {
  393.   fprintf(p.[N].rmf, "%s", p.[N].files);
  394. };
  395.  
  396. //
  397. // Remove the tmp-files
  398. //
  399.  
  400. pobj_Rm = function ( N )
  401. {
  402.   if (length (p.[N].files) != 0)
  403.   {
  404.     close (p.[N].rmf);
  405.   }
  406. };
  407.  
  408. //
  409. // Provide access to the plot-list
  410. //
  411.  
  412. _pobj_list = function ( N )
  413. {
  414.   if (!exist (N)) { N = 0; }
  415.   return p.[N];
  416. };
  417.